package controllers

import (
	"net/http"
	"meman/models/auth"
	"meman/models/alert"
	"meman/libs/paginator"
	"meman/libs/utils"
	"time"
	"strconv"
	"meman/models/events"
	"meman/sys/basic"
	"github.com/chaosue/echo-sessions"
	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/standard"
	"fmt"
)

//TODO service cfg中的常量
const MAX_MESSAGE_SEND_RETRY_TIMES  = 10
const DEFAULT_ROWS_PER_PAGE = 50

//获取日志列表
func LogList(c echo.Context) error {
	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	//使用临时session存储保存消息
	alertInfo := new(alert.Alert)

	logger := basic.Logger{}

	alive := utils.TrimSpace(c.QueryParam("alive"))
	finalStatus := utils.TrimSpace(c.QueryParam("final_status"))
	subscriberKey := utils.TrimSpace(c.QueryParam("subscriber_key"))
	classKey := utils.TrimSpace(c.QueryParam("class_key"))
	retryTimes := utils.TrimSpace(c.QueryParam("retry_times"))

	conds := make(map[string]interface{})
	if subscriberKey != "" {
		conds["subscriber_key"] = subscriberKey
	}
	if classKey != "" {
		conds["class_key"] = classKey
	}
	if retryTimes != "" {
		conds["retry_times"] = retryTimes
	}

	firstTime := utils.TrimSpace(c.QueryParam("first_push_time_start"))
	if firstTime != "" {
		timeTmp, err := time.Parse("2006-01-02 15:04:05", firstTime)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "开始时间转换时间失败!") }
		}
		conds["first_push_time_start"] = timeTmp.Unix()
	}

	endTime := utils.TrimSpace(c.QueryParam("first_push_time_end"))
	if endTime != "" {
		timeTmp, err := time.Parse("2006-01-02 15:04:05", endTime)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "结束时间转换时间失败!") }
		}
		conds["first_push_time_end"] = timeTmp.Unix()
	}


	if alive != "" {
		if ok,_ := utils.InArrayString(alive, []string{"1", "0"}); ok {
			num,err := strconv.Atoi(alive)
			if err != nil {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "alive转换int失败!") }
			}else {
				conds["alive"] = num
			}
		}else {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "alive值不在数组中,请检查!") }
		}

	}

	if finalStatus != "" {
		if ok,_ := utils.InArrayString(finalStatus, []string{"1", "0"}); ok {
			num,err := strconv.Atoi(finalStatus)
			if err != nil {
				alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "final_status转换int失败!") }
			}else {
				conds["final_status"] = num
			}
		}else {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "final_status值不在数组中,请检查!") }
		}
	}


	//分页
	var perPageNums = 0
	per := c.QueryParam("perPageNums")
	if per != "" {
		num,err := strconv.Atoi(per)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "perPageNums转换int失败!") }
		}else {
			perPageNums = num
		}

	}else {
		perPageNums = DEFAULT_ROWS_PER_PAGE  //默认50条
	}

	log := events.Log{}
	db, count := log.Count(conds)
	p := paginator.NewPaginator(c.Request().(*standard.Request).Request, perPageNums, count)
	logList,err := log.GetLogList(db, conds, p.Page(), p.PerPageNums)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "logList查询失败请检查")}
		logger.WriteMsg("error", fmt.Sprintf("[%s][LogList]can not find logList!", username))
	}

	//是否可恢复
	for _, v := range logList  {
		canbeRestored,err := log.CanbeRestored(v)
		if err != nil {
			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, err.Error())}
		}else {
			v.CanbeRestored = canbeRestored
		}

	}



	c.Render(http.StatusOK, "logList.tmpl", basic.H{
		"name":username,
		"maxRetryTimes":MAX_MESSAGE_SEND_RETRY_TIMES,
		"list":logList,
		"count":count,
		"hosts":basic.Config.Nsq,
		"paginator": p,
		"alert":alertInfo,
		//默认取值
		"subscriberKey":subscriberKey,
		"classKey":classKey,
		"alive":alive,
		"retryTimes":retryTimes,
		"finalStatus":finalStatus,
		"firstTime":firstTime,
		"endTime":endTime,
	})

	return nil
}

//查看
func LogDetail(c echo.Context) error  {
	//session 使用
	session := sessions.Default(c)
	var username string
	//中间件已判断,所以这里不需要判断
	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
		username = user.Info.Username
	}

	//使用临时session存储保存消息
	alertInfo := new(alert.Alert)

	logId := utils.TrimSpace(c.QueryParam("id"))
	logIdInt,err := strconv.Atoi(logId)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "id 转换int失败!")}
	}

	log := events.Log{}
	logDetail,err := log.GetLogDetail(logIdInt)
	if err != nil {
		alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "logDetail 获取失败!")}
	}

	c.Render(http.StatusOK, "LogDetailList.tmpl", basic.H{
		"name":username,
		"logDetail":logDetail,
		"alert":alertInfo,

	})

	return nil

}


//消息恢复
//TODO  这里需要用到 Beanstalk 的恢复 ,后面会改成redis ,现在先不做处理
func RestoreMessage(c echo.Context) error  {

	////session 使用
	//session := sessions.Default(c)
	//var username string
	////中间件已判断,所以这里不需要判断
	//if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
	//	username = user.Info.Username
	//}
	//
	////使用临时session存储保存消息
	//alertInfo := new(alert.Alert)
	//
	//var logIds events.LogIds
	//c.Bind(&logIds)
	////logIdsArray := strings.Join(logIds.LogIds, ",")
	//destHosts := utils.TrimSpace(c.Query("dest_host"))
	//
	//if len(logIds) == 0 {
	//	alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "Log ID为空!")}
	//}else if destHosts == "" {
	//	alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "请选择队列服务器!")}
	//}else {
	//	destHostsArray := strings.Split(destHosts, ",")
	//	for _,v := range destHostsArray  {
	//
	//	}
	//
	//
	//}


	return nil

}


//
//
///**
//日志下载 //TODO 这个功能先不实现
// */
//func LogDownload(c echo.Context) error  {
//	//session 使用
//	session := sessions.Default(c)
//	var username string
//	//中间件已判断,所以这里不需要判断
//	if user,ok := session.Get(USER_INFO_SESSION_KEY).(*auth.User); ok {
//		username = user.Info.Username
//	}
//
//	log := c.Query("log")
//	alertInfo := new(alert.Alert)
//	if log != "" {
//		data, err := base64.StdEncoding.DecodeString(log)
//		if err != nil {
//			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, "base64 decode 失败!") }
//		}else {
//			log = string(data)
//		}
//
//		file,err := os.Open(log)
//		defer file.Close()
//
//		if err != nil {
//			alertInfo = &alert.Alert{Flag:false, Msg:append(alertInfo.Msg, fmt.Sprintf("日志文件无法访问, 请检查权限:%s",err))}
//		}else {
//			//TODO 这里是文件的下载功能
//			chunks := make([]byte,4096,4096)
//			buf := make([]byte,4096)
//			for{
//				n,err := file.Read(buf)
//				if err != nil && err != io.EOF{
//					panic(err)
//				}
//				if 0 == n {
//					break
//				}
//				chunks=append(chunks,buf[:n]...)
//
//			}
//			fmt.Println(string(chunks))
//		}
//	}
//
//
//	//TODO: 这里还没写完, 该写获取所有日志的方法,
//	logs := []string{}
//
//
//	c.HTML(http.StatusOK, "logDownload.tmpl", gin.H{
//		"name":username,
//		"data": logs,
//		"alert":alertInfo,
//	})
//}
